﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Campus.Entities;
using CampusSite.Models;
namespace CampusSite.ViewModels
{
    public class AsistenciaVM
    {
        
		private readonly IGrupoRepository grupoRepository;
        private readonly IEstudianteRepository estudianteRepository;
        
		

        public AsistenciaVM() : this(new GrupoRepository(), new EstudianteRepository())
        {
            Meses = new List<string>();
            DiasDelPrimerMes = new List<DateTime>(12);
            DiasDelSegundoMes = new List<DateTime>(12);
            EstudiantesAsistencia = new List<EstudianteAsistenciaVM>();
            Dias = new List<string>();
        }

        private AsistenciaVM(IGrupoRepository grupoRepository, IEstudianteRepository estudianteRepository)
        {		
			this.grupoRepository = grupoRepository;
            this.estudianteRepository = estudianteRepository;        

        }

        public string ProfesorApyn { get; set; }
        
        public string Grupos { get; private set; }
        public List<string> Dias { get; private set; }

        public List<string> Meses { get; private set; }
        public List<DateTime> DiasDelPrimerMes { get; private set; }
        public List<DateTime> DiasDelSegundoMes { get; private set; }
        public List<EstudianteAsistenciaVM> EstudiantesAsistencia { get;  set; }

        /// <summary>
        /// Cargo info de los grupos y de los dias que se dictan las clases de esos grupos
        /// </summary>
        /// <param name="listGrupos"></param>
        /// <param name="grupos"></param>
        public List<int> CargarGruposyDias(List<string> listGrupos) 
        {

            List<int> grupos = new List<int>(listGrupos.Count);
            for (int x = 0; x < listGrupos.Count; x++)
            {
                grupos.Add(int.Parse(listGrupos[x]));

                Grupo grupo = grupoRepository.Find(grupos[x]);
                this.Grupos += string.Format("{0} ({1}) </br>", grupo.Nombre, grupo.Turnos.ToList()[0].DiaDeLaSemana.Nombre);

                Dias.Add(grupo.Turnos.ToList()[0].DiaDeLaSemana.Nombre);
            }

            Dias.Distinct();
            return grupos;
        }

        /// <summary>
        /// Obtiene y carga los estudiantes pertenecientes a los grupos/clases elegidos por el usuario.
        /// </summary>
        /// <param name="grupos">son los ids de grupos a partir de los cuales se obtendran los estudiantes</param>
        public void CargarEstudiantes(List<int> grupos)
        {
            var estudiantes = estudianteRepository.AllEstudiantesByGroups(grupos);

            foreach (Estudiante estudiante in estudiantes.ToList())
            {
                EstudianteAsistenciaVM estAsistVM = new EstudianteAsistenciaVM();
                estAsistVM.Apyn = string.Format("{0}, {1}", estudiante.Apellido, estudiante.Nombre);
                //si pertenece al menos a un grupo cuya actividad es anual se asume que asiste al torneo
                estAsistVM.AsisteATorneo = (estudiante.Grupos.Where(g => g.Actividad.FrecuenciaDePago.Nombre.ToLower().Trim() == "anual").ToList().Count > 0);
                estAsistVM.AnioNacimiento = estudiante.FechaNacimiento.ToString("yy");

                List<Grupo> gruposDelEstudiante = estudiante.Grupos.Where(g => g.Actividad.FrecuenciaDePago.Nombre.ToLower().Trim() == "mensual").ToList();


                
                foreach (Grupo g in gruposDelEstudiante)
                {
                    if (g.Turnos.Count > 0)
                        estAsistVM.DiasQueAsisteAClase.Add(g.Turnos.ToList()[0].DiaDeLaSemana.Nombre.Substring(0, 2).ToLower());
                }

                estAsistVM.DiasQueAsisteAClase = estAsistVM.DiasQueAsisteAClase.Distinct().ToList();

                this.EstudiantesAsistencia.Add(estAsistVM);
            }
        }

        /// <summary>
        /// Este metodo construye la secuencia de dias para cada mes que se visualizaran en la lista del profesor.
        /// La complejidad que tiene que resolver, es que la cantidad de dias de la semana es dinamica segun el Mes. Es decir, un lunes
        /// puede aparecer 5 veces en marzo, 4 en abril, etc. Se pueden analizar hasta dos dias por listado.
        /// Y el orden de visualización de cada dia tiene que corresponderse  con el orden del calendario en un mes determinado. Es decir si
        /// estoy Listando clases de los dias Sabados y Lunes, dependiendo del mes de calendario, aparecera SA o LU primeramente visualizado.
        /// </summary>
        /// <param name="idMeses">Ids de meses elegidos por el usuario. Se asume que llegan separados por comas (,)</param>
        public void CargarDiasDelPrimerMesYSegundoMes(string idMeses)
        {

            this.Meses = idMeses.Split(",".ToCharArray()).OrderBy(s => s).ToList();

            System.Globalization.DateTimeFormatInfo dateTimeFormats = new System.Globalization.CultureInfo("es-AR").DateTimeFormat;

            //tengo que buscar para cada dia, cuantas veces aparece en cada mes
            //                                                       0      1     2     3     4
            //de manera de armar dos listas strings de este estilo {"SA", "LU", "SA", "LU", "SA"}

            for (int x = 0; x < this.Meses.Count; x++)
            {
                int cantidadDias = DateTime.DaysInMonth(DateTime.Now.Year, int.Parse(this.Meses[x]));
                int indexDia1 = 0, indexDia2 = 0;

                for (int i = 1; i <= cantidadDias; i++)
                {
                    DateTime dt = new DateTime(DateTime.Now.Year, int.Parse(this.Meses[x]), i);

                    if (x == 0)
                    {//Primer Mes

                        if (dt.ToString("dddd", dateTimeFormats) == Dias[0].ToLower())
                        {
                            //si ambos son cero, el dia[0] es el primer dia del mes, entonces incremento el indice dia 2 para que comience despues
                            if (indexDia1 == 0 && indexDia2 == 0)
                                indexDia2 = 1;

                            //asistenciaVM.DiasDelPrimerMes.Insert(indexDia1, dias[0].Substring(0, 2));
                            this.DiasDelPrimerMes.Insert(indexDia1, dt);

                            if (Dias.Count > 1)
                                indexDia1 += 2;
                            else
                                indexDia1++;
                        }

                        if (Dias.Count > 1)
                            if (dt.ToString("dddd", dateTimeFormats) == Dias[1].ToLower())
                            {
                                //si ambos son cero, el dia[1] es el primer dia del mes, entonces incremento el indice dia 1 para que comience despues
                                if (indexDia1 == 0 && indexDia2 == 0)
                                    indexDia1 = 1;

                                //asistenciaVM.DiasDelPrimerMes.Insert(indexDia2, dias[1].Substring(0,2));
                                this.DiasDelPrimerMes.Insert(indexDia2, dt);
                                indexDia2 += 2;
                            }
                    }
                    if (x == 1)
                    {//Segundo mes
                        if (dt.ToString("dddd", dateTimeFormats) == Dias[0].ToLower())
                        {
                            if (indexDia1 == 0 && indexDia2 == 0)
                                indexDia2 = 1;

                            //asistenciaVM.DiasDelSegundoMes.Insert(indexDia1, dias[0].Substring(0, 2));
                            this.DiasDelSegundoMes.Insert(indexDia1, dt);

                            if (Dias.Count > 1)
                                indexDia1 += 2;
                            else
                                indexDia1++;

                        }

                        if (Dias.Count > 1)
                            if (dt.ToString("dddd", dateTimeFormats) == Dias[1].ToLower())
                            {
                                //si ambos son cero, el dia[1] es el primer dia del mes, entonces incremento el indice dia 1 para que comience despues
                                if (indexDia1 == 0 && indexDia2 == 0)
                                    indexDia1 = 1;

                                //asistenciaVM.DiasDelSegundoMes.Insert(indexDia2, dias[1].Substring(0, 2));
                                this.DiasDelSegundoMes.Insert(indexDia2, dt);
                                indexDia2 += 2;
                            }
                    }

                }
            }
        }

    }

    public class EstudianteAsistenciaVM
    {
        public string Apyn { get; set; }
        public List<string> DiasQueAsisteAClase { get; set; }
        public bool AsisteATorneo { get; set; }
        public string AnioNacimiento { get; set; }

        public EstudianteAsistenciaVM()
        {
            DiasQueAsisteAClase = new List<string>();
        }
    }
}